﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;

using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UITesting.HtmlControls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.WebHost;

using FluentAssertions;

namespace CodeStream.Testing.WebAutomation.UnitTests
{
    /// <summary>
    /// Tests the creation and destruction of an IE test instance with and without script support.
    /// </summary>
    [CodedUITest]
    public class IEInstanceTests
    {
        private static Assembly m_sampleAssembly;
        private static string m_sampleUIDefinitionCode;
        private static Uri m_htmlUri;

        private static Server webServer;

        /// <summary>
        /// Generates and Compiles the UI Definitions in the IEInstanceTests.xml file and starts a development web server.
        /// </summary>
        /// <param name="testContext">The test context.</param>
        [ClassInitialize]
        public static void Initialize(TestContext testContext)
        {
            m_sampleUIDefinitionCode = UITemplateTestExtensions.GenerateDefinitionCode(
               Assembly.GetExecutingAssembly().GetManifestResourceStream("CodeStream.Testing.WebAutomation.UnitTests.IEInstanceTests.xml"));
            m_sampleAssembly = UITemplateTestExtensions.CompileCode(m_sampleUIDefinitionCode,
                new string[]
                {
                    "System.dll",
                    "System.Core.dll",
                    new Uri(Assembly.GetAssembly(typeof(CodeStream.Testing.WebAutomation.UIDefinitionPage)).CodeBase).LocalPath,
                    new Uri(Assembly.GetAssembly(typeof(Microsoft.VisualStudio.TestTools.UITesting.BrowserWindow)).CodeBase).LocalPath,
                    new Uri(Assembly.GetAssembly(typeof(Microsoft.VisualStudio.TestTools.UITest.Extension.BrowserService)).CodeBase).LocalPath
                },
                Path.Combine(testContext.DeploymentDirectory, testContext.FullyQualifiedTestClassName + ".dll"));

            string htmlPath = Path.Combine(testContext.DeploymentDirectory, "IEInstanceTests.html");
            using (Stream input = Assembly.GetExecutingAssembly().GetManifestResourceStream("CodeStream.Testing.WebAutomation.UnitTests.IEInstanceTests.html"))
                using (FileStream output = File.Create(htmlPath))
                    input.CopyTo(output);

            webServer = new Server(18000, "/", testContext.DeploymentDirectory);
            webServer.Start();
            m_htmlUri = new Uri("http://localhost:18000/IEInstanceTests.html");
        }

        /// <summary>
        /// Stops the development web server
        /// </summary>
        [ClassCleanup]
        public static void ClassCleanup()
        {
            webServer.Stop();
        }

        /// <summary>
        /// Logs the generated code to the debug window.
        /// </summary>
        [TestInitialize]
        public void LogCodeToDebug()
        {
            Debug.WriteLine(m_sampleUIDefinitionCode);
        }

        /// <summary>
        /// Create a new browser instance, verify the page loads and script is enabled.
        /// </summary>
        [TestMethod]
        public void IEInstance_ScriptEnabled()
        {
            Type pageType = m_sampleAssembly.ShouldHaveType("TestNamespace.UIIEInstanceTestPage");
            
            using (InternetExplorerInstance browser = new InternetExplorerInstance(true))
            {                
                using (dynamic page = Activator.CreateInstance(pageType, new object[] { browser.Browser }))
                {
                    page.NavigateToUrl(m_htmlUri);
                    page.WaitForControlReady();

                    HtmlSpan header = page.Header as HtmlSpan;
                    header.InnerText.Should().Be("Script enabled");
                }
            }                              
        }

        /// <summary>
        /// Create a new browser instance, verify the page loads and script is not enabled.
        /// </summary>
        [TestMethod]
        public void IEInstance_ScriptDisabled()
        {
            Type pageType = m_sampleAssembly.ShouldHaveType("TestNamespace.UIIEInstanceTestPage");

            using (InternetExplorerInstance browser = new InternetExplorerInstance(false))
            {
                using (dynamic page = Activator.CreateInstance(pageType, new object[] { browser.Browser }))
                {
                    page.NavigateToUrl(m_htmlUri);
                    page.WaitForControlReady();

                    HtmlSpan header = page.Header as HtmlSpan;
                    header.InnerText.Should().Be("Script not enabled");
                }
            }
        }
    }
}
